package com.imooc.security.core.social.qq.api;

import java.io.IOException;

import org.apache.commons.lang.StringUtils;
import org.springframework.social.oauth2.AbstractOAuth2ApiBinding;
import org.springframework.social.oauth2.TokenStrategy;

import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * 
 * @author JZH
 * AbstractOAuth2ApiBinding中的属性：
 * 1. private final String accessToken(令牌)： 由于该属性是final的，因此AbstractOAuth2ApiBinding实现类应该是多实例对象，
 * 		每一个第三方登录用户都会有一个对应的实现
 * 2. private RestTemplate restTemplate：用于向服务提供商获取用户信息，发送请求
 */
public class QQImpl extends AbstractOAuth2ApiBinding implements QQ{

	/**
	 * OAuthen2.0协议的通用参数：分配给应用的appid
	 */
	private String appId;
	
	/**
	 * OAuthen2.0协议的通用参数：分用户的ID，与第三方应用用户标识一一对应
	 */
	private String openId;
	
	/**
	 * 获取用户的openId
	 */
	private static final String REQUEST_OPENID_URL_GET = "https://graph.qq.com/oauth2.0/me?access_token=%s";
	
	/**
	 * 向第三方应用获取用户信息，GET
	 */
	private static final String REQUEST_USER_INFO_URL_GET = "https://graph.qq.com/user/get_user_info?oauth_consumer_key=%s&openid=%s";
	
	/**
	 * 将字符串转换成json的工具类
	 */
	private ObjectMapper objectMapper = new ObjectMapper();
	
	/**
	 * 
	 * @param accessToken
	 * @param appId
	 * 
	 * QQ要求token作为参数传递
	 * ACCESS_TOKEN_PARAMETER：将accessToken放入请求体作为参数
	 * AUTHORIZATION_HEADER：将accessToken放入请求头中
	 * 
	 */
	public QQImpl(String accessToken, String appId) {
		super(accessToken, TokenStrategy.ACCESS_TOKEN_PARAMETER);
		this.appId = appId;
		String url = String.format(REQUEST_OPENID_URL_GET, accessToken);
		String result = getRestTemplate().getForObject(url, String.class);
		System.out.println("获取用户openid："+result);
		this.openId = StringUtils.substringBetween(result, "\"openid\":\"", "\"}");
	}
	
	/**
	 * 从服务提供商获取用户信息
	 */
	@Override
	public QQUserInfo getQQUserInfo(){
		// TODO Auto-generated method stub
		String url = String.format(REQUEST_USER_INFO_URL_GET, appId, openId);
		String result = getRestTemplate().getForObject(url, String.class);
		System.out.println("请求用户信息："+result);
		try {
			QQUserInfo userInfo = objectMapper.readValue(result, QQUserInfo.class);
			userInfo.setOpenId(openId);
			return userInfo;
		} catch (IOException e) {
			e.printStackTrace();
			// TODO Auto-generated catch block
			throw new RuntimeException("获取用户信息失败");
		}
	}

}
